;[April 08 2016 // John: checked opcode table against oxyron.de        ]
;[April 08 2016 // Dieter: fixed three errors found by John > ufo1.txt ]
;----------------

;
; "undocumented" opcodes
;

;www.oxyron.de/html/opcodes02.html
;(http://www.ataripreservation.org/websites/freddy.offenga/illopc31.txt)

; VICE 2.4 6510core.c

; * +1 cycle if page crossing

;----------------
;sorted by opcode table Bit 3..0

80 NOP imm 2  
02 KIL   
12 KIL  
22 KIL  
32 KIL  
42 KIL  
52 KIL  
62 KIL 
72 KIL 
82 NOP imm 2 
92 KIL  
B2 KIL  
C2 NOP imm 2  
D2 KIL  
E2 NOP imm 2  
F2 KIL 

03 SLO izx 8  
13 SLO ixy 8  
23 RLA izx 8  
33 RLA izy 8  
43 SRE izx 8  
53 SRE izy 8  
63 RRA izx 8  
73 RRA izy 8  
83 SAX izx 6  
93 AHX izy 6  
A3 LAX izx 6  
B3 LAX izy 5* 
C3 DCP izx 8  
D3 DCP izy 8  
E3 ISC izx 8  
F3 ISC izy 8  

04 NOP zp  3  
14 NOP zpx 4  

34 NOP zpx 4  
44 NOP zp  3  
54 NOP zpx 4  
64 NOP zp  3  
74 NOP zpx 4  
D4 NOP zpx 4  
F4 NOP zpx 4  // [Dieter: fixed in ufo1 // was E4]

07 SLO zp  5  
17 SLO zpx 6  
27 RLA zp  5  
37 RLA zpx 6  
47 SRE zp  5  
57 SRE zpx 6  
67 RRA zp  5  
77 RRA zpx 6  
87 SAX zp  3  
97 SAX zpy 4  // [Dieter: fixed in ufo1 // was zpx 6]
A7 LAX zp  3  
B7 LAX zpy 4  // [Dieter: fixed in ufo1 // was zpx 6]
C7 DCP zp  5  
D7 DCP zpx 6  
E7 ISC zp  5  
F7 ISC zpx 6  

89 NOP imm 2  

1A NOP     2   
3A NOP     2   
5A NOP     2   
7A NOP     2  
DA NOP     2  
FA NOP     2  

0B ANC imm 2  
1B SLO aby 7  
2B ANC imm 2 
3B RLA aby 7  
4B ALR imm 2  
5B SRE aby 7  
6B ARR imm 2  
7B RRA aby 7  
8B XAA imm 2  
9B TAS aby 5  
AB ATX imm 2 // Roberto: was LAX. Function is: A AND adr, TXA see: http://nesdev.com/undocumented_opcodes.txt 
BB LAS aby 4* 
CB AXS imm 2  
DB DCP aby 7  
EB SBC imm 2  
FB ISC aby 7  

0C NOP abs 4  
1C NOP abx 4*  
3C NOP abx 4*  
5C NOP abx 4*  
7C NOP abx 4*  
9C SHY abx 5   
DC NOP abx 4*  
FC NOP abx 4*  

9E SHX aby 5  

0F SLO abs 6  
1F SLO abx 7  
2F RLA abs 6  
3F RLA abx 7  
4F SRE abs 6  
5F SRE abx 7  
6F RRA abs 6  
7F RRA abx 7  
8F SAX abs 4  
9F AHX aby 5  
AF LAX abs 4  
BF LAX aby 4* 
CF DCP abs 6  
DF DCP abx 7  
EF ISC abs 6  
FF ISC abx 7  

; [John: following text not checked.]

;----------------
;sorted by instruction

02 KIL
12 KIL
22 KIL
32 KIL
42 KIL
52 KIL
62 KIL
72 KIL
92 KIL
B2 KIL
D2 KIL
F2 KIL

1A NOP     2
3A NOP     2
5A NOP     2
7A NOP     2
DA NOP     2
FA NOP     2

80 NOP imm 2
82 NOP imm 2
C2 NOP imm 2
E2 NOP imm 2
89 NOP imm 2

04 NOP zp  3
44 NOP zp  3
64 NOP zp  3

14 NOP zpx 4
34 NOP zpx 4
54 NOP zpx 4
74 NOP zpx 4
D4 NOP zpx 4
F4 NOP zpx 4  // [Dieter: fixed in ufo1 // was E4]

0C NOP abs 4
1C NOP abx 4*
3C NOP abx 4*
5C NOP abx 4*
7C NOP abx 4*
DC NOP abx 4*
FC NOP abx 4*

03 SLO izx 8
13 SLO ixy 8
07 SLO zp  5
17 SLO zpx 6
1B SLO aby 7
0F SLO abs 6
1F SLO abx 7

23 RLA izx 8
33 RLA izy 8
27 RLA zp  5
37 RLA zpx 6
3B RLA aby 7
2F RLA abs 6
3F RLA abx 7

43 SRE izx 8
53 SRE izy 8
47 SRE zp  5
57 SRE zpx 6
5B SRE aby 7
4F SRE abs 6
5F SRE abx 7

63 RRA izx 8
73 RRA izy 8
67 RRA zp  5
77 RRA zpx 6
7B RRA aby 7
6F RRA abs 6
7F RRA abx 7

83 SAX izx 6
87 SAX zp  3
97 SAX zpy 4 // [Dieter: fixed in ufo1 // was zpx 6]
8F SAX abs 4

93 AHX izy 6
9F AHX aby 5

A3 LAX izx 6
B3 LAX izy 5*
A7 LAX zp  3
B7 LAX zpy 4 // [Dieter: fixed in ufo1 // was zpx 6]
AF LAX abs 4
BF LAX aby 4*

AB ATX imm 2 // Roberto: was LAX. Function is: A AND adr, TAX see: http://nesdev.com/undocumented_opcodes.txt

C3 DCP izx 8
D3 DCP izy 8
C7 DCP zp  5
D7 DCP zpx 6
DB DCP aby 7
CF DCP abs 6
DF DCP abx 7

E3 ISC izx 8
F3 ISC izy 8
E7 ISC zp  5
F7 ISC zpx 6
FB ISC aby 7
EF ISC abs 6
FF ISC abx 7

0B ANC imm 2
2B ANC imm 2

4B ALR imm 2 ; named ASR in VICE

6B ARR imm 2

8B XAA imm 2 ; named ANE in VICE

9B TAS aby 5

BB LAS aby 4*

CB AXS imm 2 ; named SBX in VICE

EB SBC imm 2 ; from the VICE2.4 source code identical to 'E9 SBC imm 2'.

9E SHX aby 5

9C SHY abx 5

;================
;sorted a little bit by the amount of trouble for implementing them...

KIL "stops" the CPU.

;----------------

NOP     2 ; 1 Byte  NOP, 2 cycles
NOP imm 2 ; 2 Bytes NOP, 2 cycles

; The other NOPs with addressing mode seem to do a read access to EA //effective address

;----------------

SLO (adr) = ASL (adr) + ORA (adr)
RLA (adr) = ROL (adr) + AND (adr)
SRE (adr) = LSR (adr) + EOR (adr)
RRA (adr) = ROR (adr) + ADC (adr)

; SLO zp:
;
; 1. fetch Opcode from (PC)+
; 2. fetch adr    from (PC)+
; 3. B:=(adr)                     
; 4. T:=shift B //modify C flag //alternatively NZC
; 5. (adr):=T
; 1. A:=A op T //in parallel to instruction fetch, modify NZ flag

; RRA: ADC seems to be using the carry generated by ROR, please check.

;----------------

SAX (adr) = store A&X into (adr)

; AND does not modify flags

;----------------
//todo: check if there is a hardware problem.

LAX (adr) = LDA (adr) + LDX (adr)

; LAX zp has 3 cycles, take care.
; NZ flag modified.
;
; one trick would be loading B and X in the same cycle during the memory read,
; then to pass B through the ALU into A in the next cycle in parallel
; to an instruction fetch while modifying the flags.
; Don't know, if it will work this way.

;----------------

DCP (adr) = DEC (adr) + CMP (adr)
ISC (adr) = INC (adr) + SBC (adr)

; see SLO, except for the carry...

;----------------
### hardware problem ###

ANC #(imm) = AND #(imm) + (ASL) 

; works like AND #(imm), except that C flag is loaded with Bit 7 of the result.

;----------------

ALR #(imm) = AND #(imm) + LSR        

; first AND #(IMM) to A
; second LSR A which modifies NZC flags.

;----------------
//todo: check if there is a hardware problem.

XAA #(imm) = TXA + AND #(imm) 

; VICE: XAA is named ANE
; 
; A =(A|CONST) & X & IMM
; CONST is chip- and temperature dependent. VICE uses 0xff as CONST.

; A = (A|0xff) & X & IMM
; A =  0xff & X & IMM
; A =  X & IMM
; modifies NZ flags.

;----------------
//todo: check if there is a hardware problem.

AXS #(imm) = A&X minus #(imm) into X ; named SBX in VICE

; 2 cycles !
; NZC flags modified
; subtract without borrow ! (ALU carry input = 1)

;----------------
//todo: check if '(H+1)' is a hardware problem

SHX (addr) = store X&H into (addr)   
SHY (addr) = store Y&H into (addr)

; SHX:
;
; H is the High_Byte of the address
; (addr) = X&(H+1)
; no flags modified

; SHY uses Y instead of X.

;----------------
### hardware problem ###
//todo: check if '(H+1)' is a hardware problem.

TAS (addr) = store A&X into S, store A&X&H into (addr) 

; Freddy: store A&X into S, store S&(H+1) into (addr) //please check

; H is the High_Byte of the address
; no flags modified

;----------------
### hardware problem ###

LAS (addr) = store (addr)&S into A,X,S 

; NZ flags modified

;----------------
//todo: check if there is a hardware problem.

AHX (addr) = store A&X&H into (adr)  

; H is the High_Byte of the address
; no flags modified

;----------------
//todo: check if there is a hardware problem.

SAX (adr) = store A&X into (adr)

; no flags modified

;----------------
### hardware problem ###

ARR #(imm) = AND #(imm) + ROR

; binary mode // D flag = 0
;
;  and memory Byte to ACC, then ROR ACC.
;
;  N flag = ACC.7
;  C flag = ACC.6
;  V flag = ACC.6 XOR ACC.5
;  Z flag is set when ACC.7..0 = 0.

; decimal mode // D flag = 1
;
;  mem & ACC into tmp, ACC, then ROR ACC.
;
;  N flag = P.0     //carry that was before the ARR instruction
;  Z flag is set when ACC.7..0 = 0.
;  V flag = tmp.6 XOR ACC.6
;
;  if ((tmp&0x0f) + (tmp&1)) >0x05 then ACC3..0 +=0x06;
;
;  if ((tmp&0xf0) + (tmp&1)) >0x50
;  then  C_flag=1; ACC7..4 += 0x60;
;  else  C_flag=0;
;
; //part of the BCD correction circuitry seems to be active,
; //we better check if a carry goes from Bit 3..0 into Bit 4 then.

; NVZC flags modified

;----------------
//end of file
